﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace GameFrameWork
{
    public interface IUILoadAssetResult : IAwaiter<IUILoadAssetResult, GameObject>, ICancelable
    {
        GameObject Result { get; }
    }

    public class UILoadAssetResult : IUILoadAssetResult
    {
        private LoadAssetAwaiter loader;
        private Transform parent;

        public GameObject Result { get; private set; }
        public bool IsCompleted { get; set; }

        private bool m_IsCancel;
        protected Action continuation = null;

        public UILoadAssetResult(LoadAssetAwaiter loader, Transform parent = null)
        {
            this.loader = loader;
            this.parent = parent;
            if (loader.IsCompleted)
            {
                IsCompleted = true;
                OnFinish(loader.Asset != null);
            }
            else
            {
                loader.OnFinish += OnFinish;
            }
        }

        private void OnFinish(bool success)
        {
            IsCompleted = true;
            if (success && !loader.IsUnload && !m_IsCancel)
            {
                var prefab = loader.Asset as GameObject;
                if (prefab != null && prefab)
                {
                    Result = GameObject.Instantiate(prefab, parent, false);
                }
            }
            continuation?.Invoke();
            continuation = null;
        }

        public void Cancel()
        {
            m_IsCancel = true;
            if (Result != null)
            {
                GameObject.DestroyImmediate(Result);
                Result = null;
            }
        }

        public IUILoadAssetResult GetAwaiter()
        {
            return this;
        }

        public GameObject GetResult()
        {
            return Result;
        }

        public void OnCompleted(Action continuation)
        {
            if (IsCompleted || m_IsCancel)
            {
                continuation?.Invoke();
                return;
            }
            this.continuation += continuation;
        }

    }
}


